
`include "common_header.verilog"

//  *************************************************************************
//  File : register_map_mgmii
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited. 
//  Copyright (c) 2008 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Daniel Koehler
//  info@morethanip.com
//  *************************************************************************
//  Description : Configuration Registers for MII/GMII/XGMII RS.
//  Version     : $Id: register_map_mgmii.v,v 1.2 2012/12/17 11:05:06 dk Exp $
//  *************************************************************************

module register_map_mgmii (

   reset_reg_clk,
   reg_clk,
   reg_rd,
   reg_wr,
   reg_sel,
   reg_data_in,
   reg_data_out,
`ifdef MTIP_DIR_CONFIG
   mode_set_wr,
   set_1g_mode,
`endif
   if_mode_set,
   if_mode_ena,
   mii_ena_10,
   mgmii_ena,
   mii_ena);

// `include "mtip_10geth_pack_package.verilog"

input   reset_reg_clk;          //  Asynchronous Reset - reg_clk Domain
input   reg_clk;                //  ReferenceInterface Clock
input   reg_rd;                 //  Register Read Strobe
input   reg_wr;                 //  Register Write Strobe
input   [3:0] reg_sel;          //  Register Address
input   [15:0] reg_data_in;     //  Write Data for Host Bus
output  [15:0] reg_data_out;    //  Read Data to Host Bus
`ifdef MTIP_DIR_CONFIG
input   mode_set_wr;            // one reg_clk clock pulse to write the mode settings
input   set_1g_mode;            // Value to be written in the bit MAC_IF_MODE[1]
`endif
input   [1:0] if_mode_set;      //  Interface selection from extern control (async)
output  [1:0] if_mode_ena;      //  Current Interface selection indication
output  mii_ena_10;             //  indicate 10Mbps for MII (control to RMII)
output  mgmii_ena;              //  interface mode to use MII/GMII (1) or XGMII (0)
output  mii_ena;                //  interface mode to use MII (1) or GMII (0)

reg     [15:0] reg_data_out; 
wire    [1:0] if_mode_ena; 
wire    mii_ena_10; 
wire    mgmii_ena; 
wire    mii_ena; 

wire    [1:0] if_mode_set_s;    //  Interface selection from extern control (async)
reg     [1:0] if_mode_r; 
reg     mii_ena_10_r; 
reg     [1:0] if_mode_ena_r;    //  final mode

//  Clock Synchronizer using DFFs
mtip_xsync #(2) MS (
          .data_in(if_mode_set),
          .reset(reset_reg_clk),
          .clk(reg_clk),
          .data_s(if_mode_set_s));
          
//  -------------
//  IF_MODE register
//  -------------
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_1
   if (reset_reg_clk == 1'b 1)
      begin
      if_mode_r <= 2'b 00;	
      mii_ena_10_r <= 1'b 0;	
      if_mode_ena_r <= 2'b 00;	
      end
   else
      begin
      if (reg_wr == 1'b 1 & reg_sel == 4'b 0000)
         begin
         if_mode_r <= reg_data_in[1:0];	
         mii_ena_10_r <= reg_data_in[4];	
         end
      `ifdef MTIP_DIR_CONFIG       
      else if( mode_set_wr==1'b 1 )
         begin
         if_mode_r[0] <= 1'b 0;	
         if_mode_r[1] <= set_1g_mode;   // enable selection of GMII (1) or XGMII (0)
         mii_ena_10_r <= 1'b 0;	
         end
      `endif

        //  determine final mode depending on configured or external
      if_mode_ena_r <= if_mode_r | if_mode_set_s;	

      end
   end

//  wire outputs

assign if_mode_ena      = if_mode_ena_r;        //  Current Interface selection indication
assign mii_ena_10       = mii_ena_10_r;         //  indicate 10Mbps for MII (control to RMII)
assign mgmii_ena        = if_mode_ena_r[0] | if_mode_ena_r[1]; //  interface mode to use MII/GMII (1) or XGMII (0)
assign mii_ena          = if_mode_ena_r[0];     //  interface mode to use MII (1) or GMII (0), rxclk domain

//  -------------
//  Read MUX
//  -------------
always @(reg_sel or if_mode_r or mii_ena_10_r or if_mode_ena_r)
   begin : process_2
   case (reg_sel)

//  IF_MODE
   4'b 0000:
      begin
      reg_data_out = {11'b 00000000000, mii_ena_10_r, 2'b 00, if_mode_r};
      end

//  IF_STATUS
   4'b 0001:
      begin
      reg_data_out = {12'h 000, 2'b 00, if_mode_ena_r};	
      end

   default:
      begin
      reg_data_out = 16'h 0000;	
      end

   endcase
   end

endmodule // module register_map_mgmii

